<?php
class WebServiceServer {
	protected $cfg;
	
	protected $key;
	protected $version;

	public function __construct($cfg = array()) {
		$this->setCfg($cfg);
		$this->initial();
	}

	protected function extractVersion($version) {
		$tmp = explode(".", $version);
		$tmp[0] = isset($tmp[0]) ? (int) $tmp[0] : 0;
		$tmp[1] = isset($tmp[1]) ? (int) $tmp[1] : 0;
		$tmp[2] = isset($tmp[2]) ? (int) $tmp[2] : 0;

		return $tmp;
	}

	protected function checkSignature($num_files, $function_name, $parameters, $signature) {
		$good_signature = sha1($this->key . $num_files . $function_name . $parameters);

		if ($good_signature == $signature) {
			return TRUE;
		}
		return FALSE;
	}

	protected function checkVersion($client_version) {
		if ( ($client_version != '0.0.0') ) {
			list($cx, $cy, $cz) = $this->extractVersion($client_version);
			list($sx, $sy, $sz) = $this->extractVersion($this->version);

			if ( ($sx != $cx) || ($sy < $cy) ) {
				return FALSE;
			}
		}

		return TRUE;
	}

	protected function handleRequest($function_name, $parameters, $files) {
		return call_user_func_array($function_name, $parameters); 
	}

	public function process() {
		//should consider magic_quotes_gpc
		$function_name = $_REQUEST['function_name'];
		$parameters = $_REQUEST['parameters'];
		$signature = $_REQUEST['signature'];
		$client_version = isset($_REQUEST['version']) ? $_REQUEST['version'] : '0.0.0';
		$num_files = sizeof($_FILES) ? (sizeof($_FILES['file']['name'])) : 0;

		$ret = $this->checkSignature($num_files, $function_name, $parameters, $signature);
		if (!$ret) {
			http_send_status(405);
			exit();
		}

		$ret = $this->checkVersion($client_version);
		if (!$ret) {
			http_send_status(406);
			exit();
		}

		$parameters = json_decode($parameters, TRUE);
		$response = $this->handleRequest($function_name, $parameters, $_FILES);

		echo json_encode($response);
	}
	
	protected function setCfg($cfg) {
		$this->cfg = require FRAMEWORK_WEBSERVICE_SERVER_ROOT . 'config.php';
		
		foreach($cfg as $key => $val) {
			if(array_key_exists($key, $this->cfg)) $this->cfg[$key] = $val;
		}
	}
	
	protected function initial() {
		$this->key = $this->cfg['key'];
		$this->version = $this->cfg['version'];
		
		//discard magic quote gpc
		if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() == 1) {
			$_GET = $this->stripslashesDeep($_GET);
			$_POST = $this->stripslashesDeep($_POST);
			$_COOKIE = $this->stripslashesDeep($_COOKIE);
			$_REQUEST = $this->stripslashesDeep($_REQUEST);
		}
	}
	
	protected function stripslashesDeep($var) {
		if(empty($var)) return $var;
		
		return is_array($var) ? array_map(array($this, __FUNCTION__), $var) : stripslashes($var);
	}
}
?>
